//
//  tutu_core.c
//  device
//
//  Created by ffly on 2021/3/14.
//

#include "xlx_define.h"
#include "xlx_core.h"
#include "xlx_tms_service.h"

static const char* TAG = "Core";

#define BATT_CHARGE_INIT    0       // 拔掉USB
#define BATT_CHARGING       1       // 正在充电中
#define BATT_CHARGE_FULL    2       // 插入了usb，充电完成
char batt_charge_status = BATT_CHARGE_INIT;

#if 1
TutuQueue TUTUG(queue) = {0};
TutuThread TUTUG(thread) = {0};
TutuOS TUTUG(os) = {0};
TutuSocket TUTUG(socket) = {0};
TutuFile TUTUG(file) = {0};
TutuConfig TUTUG(config) = {0};
TutuServerCfg TUTUG(servercfg) = {0};
TutuGlobalParam TUTUG(param) = {0};
TutuTcpSocket TUTUG(tcp) = {0};
#else

TutuTimer TUTUG(timer) = {0};
TutuBattery TUTUG(battery) = {0};

#endif

/**
 * 工厂测试模式
 * 1：测试模式  0：正常模式
 */
int sync_ntp_time_flag = 0;         // 开机后是否同步NTP时间
int tutu_factory_test_mode = 0;

int tutu_factory_mic_irq = 0;//工厂测试，声控麦克检测中断数
int tutu_is_bigendian = 0;//大小端
int tutu_show_logger = 1;//打印控制台日志
int tutu_gps_logger = 0;//是否开启gps日志打印
int tutu_gsensor_logger = 0;//是否开启gsensor日志,上传服务器
int tutu_net_logger = 0;//开启网络日志
int tutu_net_logger_level = 2;//网络日志级别,All:0  Debug:1  Info:2  Error:3
int tutu_save_config_flag = 0;//保存配置文件标识
char tutu_device_imei[18] = {0};

char tutu_play_sos_key_tts = 0;     // 按鍵是是否提示声音

uint32_t tutu_process_time_count = 0;      //整个任务计时器

//上报开机状态
static char tutu_upload_startup_time = 0;

static uint16_t gps_auto_switch_check_tick = 0;  // GPS 自动开启
static uint16_t green_led_delay_turn_off_tick = 0;  // 绿色LED延时关闭tick
static uint16_t speaker_delay_turn_off_tick = 0;  // 播放后延时关闭功放

static char auto_fly_flag = 0;          // 是否进入了自动飞行模式
static char delay_auto_sos_alarm_falg = 0;  // 是否延时上报SOS告警标志

static uint32_t auto_fly_sos_exit_tick = 0; // 记录当按了SOS键后，退出飞行模式的秒数

static TutuThreadHandle *tutu_core_main_task_thread = NULL;     
static TutuThreadHandle *tutu_core_main_watch_thread = NULL;   

static char tutu_app_init_all_flag = 0; // 解决烧录程序后第一次只能跑一部分，初始不完全问题

/*
* 设置延时关闭绿色LED灯时间(秒) 4G指示灯
*/
void set_led_delay_turn_off_tick(uint16_t tick){
    green_led_delay_turn_off_tick =  tick;
}

/*
* 设置 延时上报SOS告警标志
*/
void set_delay_auto_sos_alarm_falg(char flag){
    delay_auto_sos_alarm_falg =  flag;
}

char get_auto_fly_flag(void){
    return auto_fly_flag;
}

/*
*  播放后延时关闭功放 省点
*/
void set_speaker_delay_turn_off_tick(uint16_t tick){
    speaker_delay_turn_off_tick =  tick;
}

//初始化所有参数
void xlx_core_init(void){
#if 1
    TutuQueue_Init(&TUTUG(queue));
    TutuThread_Init(&TUTUG(thread));
    TutuOS_Init(&TUTUG(os));
    TutuFile_Init(&TUTUG(file));
    TutuConfig_Init();
    
    TutuSocket_Init(&TUTUG(socket));
    
    //TutuTcpSocket_Init(&TUTUG(tcp));        // 开启socket线程    
    // xlx_tms_service_init();  // 延时启动

#else
    // 记录唤醒数据, 此时时间不对
    g_curret_wakeup_src.ap_reset_state = (unsigned char )cm_pm_get_power_on_reason();
    g_curret_wakeup_src.cp_reset_state = 0; // cp未知
    g_curret_wakeup_src.wakeup_source = 0;  // 不知道唤醒
    memcpy(g_curret_wakeup_src.ap_checksum, get_CHECKCODE(), sizeof(g_curret_wakeup_src.ap_checksum));
    g_curret_wakeup_src.ap_version = get_version_code();    
    g_curret_wakeup_src.datetime = DATETIME_MIN;    // 先使用默认        

    // 保存唤醒源数据到eprom g_tutuos.get_utc_timestamp();
    // 先导出
    tutu_load_wakeup_src_cfg();
    wakup_src_add(&g_sys_wakeup_src,&g_curret_wakeup_src);
    tutu_save_wakeup_src_cfg();     

    TutuTimer_Init(&TUTUG(timer));
    
    TutuRil_Init(&TUTUG(ril));
    tutuapi_init();
    tutumode_init();      

#if 0
// 打印波形
    extern tutu_wave_out_gpio_init(void);
    tutu_wave_out_gpio_init();
#endif
#endif
}

void tutucore_load_imei(void){
    char imei[18] = {0};
    int i = 0,j = 0;
    char a = 0;
    
    TUTU_LOGI(TAG, "---------  Imei loading... -----------");
    memcpy(&imei[1], TEST_IMEI,16);
    
    //sprintf(tutu_device_imei, "0%s",TEST_IMEI)
    memcpy(tutu_device_imei,TEST_IMEI,16);
 
    TUTU_LOGI(TAG, "imei = %s",tutu_device_imei);

    //char转bcd编码
    for(i = 0;i < 8;i++){
        a = (imei[j++] - '0') << 4;
        a = a + (imei[j++] - '0');
        g_tutuconfig.imei[i] = (char)(a);
    }
}

/**
 * 恢复正常默认(重置工厂测试，默认1小时)
 */
void tutucore_reset_factory_test_mode() {
    if (tutu_factory_test_mode != 1) return;
    static uint32_t factory_test_mode_time = 0;
    if (tutu_factory_test_mode == 1 && factory_test_mode_time == 0) {
        factory_test_mode_time = tutu_process_time_count;
    }
    if (tutu_process_time_count - factory_test_mode_time >= 3600) {
        xlx_action_data data = {0};
        data.t = ACTION_TYPE_AT;
        data.argc = 2;
        char params[2][32] = {"testmode", "exit"};
        data.argv = (char **)params; 
        tutucation_testmode(&data);
        factory_test_mode_time = 0;
    }
}

/*
* 上报心跳数据到服务器
* 114.040800,22.650040
*/
void tutucore_upload_heart(){  
    //只要登陆成功，第一次就会上传一次心跳数据
    if(g_tutuparam.flag_enter_heart_code == 1){
        g_tutuparam.flag_enter_heart_code = 0;

        TUTU_LOGI(TAG, "Uploading heart");
        //更新电量
        g_tutuparam.device_status.power = 93;

        TUTU_LOGI(TAG, "GPS data updating...");        
        //更新卫星数量
        g_tutuparam.device_status.satellite_size = 12;
        
        //先清空状态，然后在一次设置状态
        g_tutuparam.device_status.status = 0;
        TUTU_LOGI(TAG, "GPS data updating2...");        
        //更新状态
        g_tutuparam.device_status.satellite_size = 1;

        // 更新充电状态

        //是否插上usb

        TUTU_LOGI(TAG, "CSQ getting...");
        //更新4g设备信号值
        g_tutuparam.device_status.gsm_signal = 93;

        TUTU_LOGI(TAG, "gsm_signal=%d", g_tutuparam.device_status.gsm_signal);
      
        //发送心跳包
        tutuapi_send_heart_msg2();
        TUTU_LOGI(TAG, "gsm_signal 2=%d", g_tutuparam.device_status.gsm_signal);

        if(g_tutuparam.up_sync_status_counter > 0){
            g_tutuparam.up_sync_status_counter--;
            //发送设备状态同步到服务器
            tutuapi_send_device_status_msg();
        }
      
    } 
}

//临时拷贝飞行模式数据
TutuFlyingMode _pri_fly_mode = {0};

//飞行模式
/*
* 
*/
void tutucore_fly_mode(void){
#if 0    

    // 如果指令控制，停止飞行模式，则退出飞行模式
    if(g_tutuconfig.fly_mode.enable == 0){
        g_tutuconfig.fly_mode.step = 0;
        g_tuturil.disable_flymode();//关闭飞行模式
        tutumode_switch(TUTU_WORK_MODE_NORMAL);//切换到正常模式
        return;
    }

    switch (g_tutuconfig.fly_mode.step)
    {
    case 0://初次进入,也就是收到进入飞行模式的指令
        {
            g_tutuconfig.fly_mode.step = 1;
            //拷贝临时变量
            memcpy(&_pri_fly_mode,&(g_tutuconfig.fly_mode),sizeof(TutuFlyingMode));
            //关闭gps定位            
            TUTU_LOGI(TAG, "FlyModeStep1");
            g_tutugps.disable_gps();
        }
        break;
    case 1://重新根据指令的值，刷新进入退出倒计时
        {
            //每循环一次，重置进入和退出时间
            g_tutuconfig.fly_mode.step = 2;
            _pri_fly_mode.enter_time = g_tutuconfig.fly_mode.enter_time * 60;//分钟转换成秒
            _pri_fly_mode.exit_time = g_tutuconfig.fly_mode.exit_time * 60;//分钟转换成秒
            TUTU_LOGI(TAG, "---------init fly mode---enter=%d---exit=%d----",_pri_fly_mode.enter_time,_pri_fly_mode.exit_time);
        }
        break;
    case 2://倒计时，进入飞行模式
        {
            if(_pri_fly_mode.enter_time > 0){
                _pri_fly_mode.enter_time--;
            }else{
                g_tutuconfig.fly_mode.step = 3;
                g_tuturil.enable_flymode();//进入飞行模式
                TUTU_LOGI(TAG, "---------enter fly mode----------");
            }
            
        }
        break;
    case 3:// 倒计时，退出飞行模式
        {
            if(_pri_fly_mode.exit_time > 0){
                _pri_fly_mode.exit_time--;//退出飞行模式，倒计时
            }else{
                TUTU_LOGI(TAG, "---------exit fly mode----------");
                g_tutuconfig.fly_mode.step = 4;
                g_tuturil.disable_flymode();//关闭飞行模式

                tutumode_switch(TUTU_WORK_MODE_NORMAL);//切换到正常模式，上报完定位后，需要在切会飞行模式
                g_tutuparam.flag_enter_heart_code = 1;//可以不用等待就进入上报心跳
                g_tutuparam.flag_enter_gps_pos_code = 1;//可以不用等待就进入上报位置

                // 如果等于0，就是无限循环
                if(g_tutuconfig.fly_mode.counter != 0){
                    if(_pri_fly_mode.counter > 0){
                        _pri_fly_mode.counter--;
                    }else{
                        //循环完就禁止飞行模式
                        g_tutuconfig.fly_mode.enable = 0;                        
                        tutu_save_config_flag = 1;
                    }
                }

                //开启gps
                g_tutugps.enable_gps();
                g_tutuparam.is_login_server = 0;
                g_tutuparam.server_connected = 0;//重置服务器连接状态
                g_tuturil.reset_check_sim_status();//重置sim检测状态
            }
        }
        break;
    case 4:
        {
            //步骤4，等待进入正常模式，然后上报一次数据
            //然后重新进入飞行模式等待期
        }
        break;
    default:
        break;
    }
#endif    
}

/*
 * 保持多久定位
 * 唤醒gps上电，持续定位s秒后，如果设备处于静止，则关闭gps电源
 * @param s 持续秒数
 */
void tutucore_hold_gps(int s){    
    //0：静止   1：震动   2：检测中
    g_tutuparam.shake_state = 1;//设置为震动
    g_tutuparam.shake_time = s;
   
}

/*
设置NTP同步时间状态
*/
void tutu_set_sync_ntp_state(unsigned char sync_flag){
    sync_ntp_time_flag = sync_flag;
}

unsigned char tutu_get_sync_ntp_state(void){
    return sync_ntp_time_flag;
}

/*
 * 网络功能
 */
void tutucore_network(){
 
    // static unsigned int  sync_ntp_time_delay_cnt = 0;

    if(g_tutuparam.net_once_hold_time > 0){
        //网络持续可使用倒计时
        g_tutuparam.net_once_hold_time --;
    }

#if 1   
    TUTU_LOGI(TAG, "<<<,%d, %d, %d, %d", 
        g_tutuparam.net_once_hold_time, 
        g_tutuparam.server_connected,
        g_tutuparam.flag_enter_heart_code,
        g_tutuparam.up_sync_status_counter
    );

    if(1){//开启网络功能

        //如果网络开启或者倒计时有效，则都开启网络
        if(1 || (g_tutuparam.net_once_hold_time > 0)){

            // 这里应该是WIFI是否正常连接到AP                
            if(1){      //说明设备有插卡，并且流量是打开的
                if(g_tutuparam.server_connected == 0){
                    g_tutuparam.flag_enter_heart_code = 1;//第一次连接上服务器，要求立即上报心跳
                    g_tutuparam.up_sync_status_counter = 3;//第一次连接上服务器，要求立即上报设备当前状态
                    g_tutuparam.server_connected = 2;//设置标记为，正在准备连接服务器
                    tutuapi_connect_server();
                }

#if 0
                // 同步NTP时间
                if(!sync_ntp_time_flag){
                    if(sync_ntp_time_delay_cnt % 10 == 5){
                        tutu_sync_ntp();
                    }

                    TUTU_LOGI(TAG, "sync_ntp_time_delay_cnt=%d", sync_ntp_time_delay_cnt);
                    sync_ntp_time_delay_cnt++;
                }                               
#endif                
            }


            // 如果和服务器网络断开，则开始检查是否插sim卡，pdp是否激活
            if(g_tutuparam.server_connected == 3){
                //　正常模式开启这个灯，飞行模式不需要开启

                //如果设备处于震动状态，并且开启网络重启，并且超过10s才重启的
                if(g_tutuparam.network_restart_cfg.enable == 1 && g_tutuparam.network_restart_cfg.time > 10){
                    //说明在使用，需要加快网络检查
                    g_tutuparam.network_restart_cfg.time = 10;
                    g_tutuparam.network_restart_cfg.check_counter = 0;
                }

                // 如果还没有开启网络重启
                if(g_tutuparam.network_restart_cfg.enable == 0){
                    if(1){
                        //如果有卡，10秒重启网络，重新连接服务器
                        g_tutuparam.network_restart_cfg.enable = 1;
                        g_tutuparam.network_restart_cfg.time = 10;
                        g_tutuparam.network_restart_cfg.check_counter++;
                        
                        TUTU_LOGI(TAG, "network_restart_cfg.check_counter=%d",g_tutuparam.network_restart_cfg.check_counter);
                        
                        if(g_tutuparam.network_restart_cfg.check_counter > 50){
                            TUTU_LOGI(TAG, "RST %s:%d", __FUNCTION__, __LINE__);
                            g_tutuos.restart();//重启设备
                        }
                    } else {
                        //如果无卡，则不开启网络重启检测
                        g_tutuparam.network_restart_cfg.enable = 0;
                        g_tutuparam.network_restart_cfg.check_counter = 0;
                    }
                }
            }


            //已经连上服务器
            if(g_tutuparam.is_login_server == 1 && g_tututcp.is_connect() == 1){
      
                g_tutuparam.network_restart_cfg.check_counter = 0;

                //上报设备开机时间
                if(tutu_upload_startup_time == 0){
                    tutu_upload_startup_time = 1;
                    TUTU_LOGI(TAG, "Uploading startup time (%s:%d)", __FUNCTION__, __LINE__);
                    tutuapi_send_net_logger_print("[tutu_core.c] device startup time:%ld",(g_tutuos.get_utc_timestamp() - tutu_process_time_count));
                }
                //上报心跳
                tutucore_upload_heart();
            }

        }else{
            if(g_tutuparam.server_connected){
                TUTU_LOGI(TAG, "TCP are closed!");
                g_tutuparam.server_connected = 0;
                g_tututcp.close_server();          
            }

        }
    }else{
        TUTU_LOGI(TAG, "TCP and GPS are closed!!!");
        g_tutuparam.server_connected = 0;
        g_tututcp.close_server();
    }

#endif    
}

static char low_voltage_alert_flag = 0;


//上报低电报警
void tutucore_upload_low_voltage_alert(void){
#if 0    
    char sndmsg[256] = {0};
    TutuMsgAlert alert={0};
    TutuNmeaMsg *gpsmsg = NULL;
    TutuMsgBaseStation *station = NULL;
    int i = 0;
    int station_size = 0;
    int offset = 0;
    char lat[12] = {0};
    char lng[12] = {0};

    //更新电量
    TUTU_LOGI(TAG, "Uploading lowPower alatr")
    alert.power = g_tutubattery.get_vol_power();
    //更新卫星数量
    alert.satellites = g_tutugps.get_gps_info()->posslnum;
    //更新4g设备信号值
    alert.station_signal = (int)(g_tuturil.get_sim_signal()/31.0 * 100);
    // TUTU_LOGI(TAG, "GET_UTC_timestamp %s:%d", __FUNCTION__, __LINE__);
    alert.upload_time = g_tutuos.get_utc_timestamp();

    //获取定位数据
    gpsmsg = g_tutugps.get_gps_info();
    tutu_latlng2str(gpsmsg->latitude,lat,1);
    tutu_latlng2str(gpsmsg->longitude,lng,0);
    TUTUSprintf(sndmsg,"LowVoltage=%d@%s|%s|",alert.power,lng,lat);

    //获取附近基站
    station_size = g_tutustation.get_list_size();
    offset = strlen(sndmsg);

    //拼装基站数据
    for(i = 0;i < station_size && i < 3;i++){
        station = g_tutustation.get_list_index(i);
        if(station){
            TUTUSprintf(sndmsg + offset,"%d|%d|%d|%lu|%d|",station->mcc,station->mnc,station->lac,station->cellid,station->signal);
            offset = strlen(sndmsg);
        }
    }

    //上报数据到服务器
    tutuapi_send_upload_alert_msg(&alert,sndmsg,strlen(sndmsg));
#endif    
}

//上报SOS报警
/*
* 开启SOS后，打开GPS定位， 并清除倒计时
*/
void tutucore_upload_SOS_alert(void){
#if 0    
    char sndmsg[256] = {0};
    TutuMsgAlert alert={0};
    TutuNmeaMsg *gpsmsg = NULL;
    TutuMsgBaseStation *station = NULL;
    int i = 0;
    int station_size = 0;
    int offset = 0;
    char lat[12] = {0};
    char lng[12] = {0};

    TUTU_LOGI(TAG, "Open GPS after SOS");
    g_tutugps.enable_gps();
    tutucore_hold_gps(180); // 3开启GPS 3分钟

    //更新电量
    alert.power = g_tutubattery.get_vol_power();
    //更新卫星数量
    alert.satellites = g_tutugps.get_gps_info()->posslnum;
    //更新4g设备信号值
    alert.station_signal = (int)(g_tuturil.get_sim_signal()/31.0 * 100);
    // TUTU_LOGI(TAG, "GET_UTC_timestamp %s:%d", __FUNCTION__, __LINE__);
    alert.upload_time = g_tutuos.get_utc_timestamp();

    //获取定位数据
    gpsmsg = g_tutugps.get_gps_info();
    tutu_latlng2str(gpsmsg->latitude,lat,1);
    tutu_latlng2str(gpsmsg->longitude,lng,0);
    TUTUSprintf(sndmsg,"SOS=@%s|%s|",lng,lat);

    //获取附近基站
    station_size = g_tutustation.get_list_size();
    offset = strlen(sndmsg);

    //拼装基站数据
    for(i = 0;i < station_size && i < 3;i++){
        station = g_tutustation.get_list_index(i);
        if(station){
            TUTUSprintf(sndmsg + offset,"%d|%d|%d|%lu|%d|",station->mcc,station->mnc,station->lac,station->cellid,station->signal);
            offset = strlen(sndmsg);
        }
    }

    //上报数据到服务器
    tutuapi_send_upload_alert_msg(&alert,sndmsg,strlen(sndmsg));
#endif    
}


static void on_station_result_event(){
#if 0    
    if(low_voltage_alert_flag == 1){
        low_voltage_alert_flag = 0;
        tutucore_upload_low_voltage_alert();
    }
#endif    
}

#define LOW_VOLTAGE_CHECK_INTERVAL 300      // 300秒 5分钟
// 检测低电压报警
void tutucore_check_low_voltage(void){
#if 0    
    static char auto_poweroff_chec_count = 0;    
    int now_voltage;

    if((tutu_process_time_count % LOW_VOLTAGE_CHECK_INTERVAL) == 0){
        now_voltage = g_tutubattery.get_vol_power();     // 电量百分比
    }
    else {
        return;
    }

    //5分钟检测一次电压
    if(g_tutuparam.low_voltage_cfg.upload == 0){
        TUTU_LOGI(TAG, "lowVoltage checking...");
        if( now_voltage < g_tutuconfig.low_voltage_threshold){
            g_tutuparam.low_voltage_cfg.counter++;
        }else{
            g_tutuparam.low_voltage_cfg.counter = 0;
        }

        //累计检测到3次低电，才准备上报低电告警
        if(g_tutuparam.low_voltage_cfg.counter >= 3){
            g_tutuparam.low_voltage_cfg.counter = 0;

            //插了usb在充电，就不报警
            if(g_tutubattery.has_connect_usb() == 0){
                g_tutuparam.low_voltage_cfg.upload = 1;

                TUTU_LOGI(TAG, "Battery low alarm!!!");
                //  增加低电报警
                g_tutuos.play_tts("电量较低，请及时充电！",0,0);
                //cm_local_tts_play("电量较低，请及时充电！",  strlen("电量较低，请及时充电！"), NULL, "Chinese");

                //上报低电告警
                low_voltage_alert_flag = 1;
                g_tutustation.set_result_cb(on_station_result_event);
                g_tutustation.start_scan();

                //限制多久后会重新上报一次  3600*300
                g_tutuparam.low_voltage_cfg.alert_interval = 3*3600/LOW_VOLTAGE_CHECK_INTERVAL;     // 根据间隔计算  3小时
                //g_tutuparam.low_voltage_cfg.alert_interval = 5;
                //g_tutuparam.low_voltage_cfg.alert_interval = 2*60*60;//3小时
            }
        }
    }

    //还原低电报警状态
    if(g_tutuparam.low_voltage_cfg.upload == 1){
        if(g_tutuparam.low_voltage_cfg.alert_interval > 0){
            g_tutuparam.low_voltage_cfg.alert_interval--;
        }
        else {
            g_tutuparam.low_voltage_cfg.upload = 0;
        }
    }


 /********************************************************************/   
    //用来保护电池电压过低，提前判断关机
    //电压过低，直接关机
    TUTU_LOGI(TAG, "Lowpower checking...");
    if(0 == now_voltage){
        if(g_tutubattery.has_connect_usb() != 1){   // 没有接USB
            if(auto_poweroff_chec_count++ > 3){       //说明可能电压低，需要走低电关机逻辑
                // 如果连续12次电压都低于3400，则关机
                TUTU_LOGI(TAG, "---low voltage shutdown---");
                g_tutuos.power_off();
            }
        }else{
            //如果插着usb，则不走低电关机逻辑
            if(auto_poweroff_chec_count){
                auto_poweroff_chec_count = 0;
            }
        }
    }else{
        //如果检测到超过3400的，说明可能电压不稳定，所以不走低电关机逻辑
        if(auto_poweroff_chec_count){
            auto_poweroff_chec_count = 0;
        }
    }
 /********************************************************************/   
#endif 
}


/**
 * 主线任务
 */
void tutucore_main_task(void *params){  
    unsigned char wakeup_src_saved = 0; // 是否获取到正确时间后保存唤醒源到NVRAM文件
    unsigned long current_timestamp = 0;

    //开机默认为震动，持续5分钟
    //好让设备可以定位
    tutucore_hold_gps(180);

    //加载设备imei号
    tutucore_load_imei();

    tutu_process_time_count = 0;

    TUTU_LOGI(TAG, "%s(%d)", __FUNCTION__, __LINE__); 
    while(1){

        g_tutuos.sleep(1);  // 使用 1s 事件
      
        tutu_process_time_count++;
        
#if 0        
        // 获取到网络时间后保存开机时间
        if(0 == wakeup_src_saved){
            if(0 ==tutu_get_sync_ntp_state()){   
                current_timestamp =  g_tutuos.get_utc_timestamp();
                TUTU_LOGI(TAG, "curr timestamp: %lu", current_timestamp);                
                g_curret_wakeup_src.datetime = current_timestamp;             
                update_last_datetime_and_save(&g_sys_wakeup_src, g_curret_wakeup_src.datetime);  
                wakeup_src_saved = 1;
            }
        }
#endif        
        //工厂模式
        if(tutu_factory_test_mode == 1){
            TUTU_LOGI(TAG, ".");
            continue;
        }

        //每5s，检测一次是否有需求，要保存配置文件
        if((tutu_process_time_count % 5 == 0) && tutu_save_config_flag == 1){
            tutu_save_config_flag = 0;
            tutuconfig_save();
        }

        //执行模式代码
        // tutumode_doframe();
        //TUTU_LOGI(TAG, "m2");
        //网络功能
        tutucore_network();


#if 0
// 测试 关闭GPS
        if(tutu_process_time_count % 10 == 0){
            TUTU_LOGI(TAG, "---t=%ld--mode=%d--shake=%d--shaketime=%d--connect=%d--ril=%d-csq=%d---",
            tutu_process_time_count,g_tutuconfig.mode,g_tutuparam.shake_state,g_tutuparam.shake_time,
            g_tututcp.is_connect(),g_tuturil.get_sim_status(),g_tuturil.get_sim_signal());

            tutuapi_send_net_logger_debug("t=%ld,mode=%d,shake=%d,shaketime=%d,connect=%d,status=%d",
            tutu_process_time_count,g_tutuconfig.mode,g_tutuparam.shake_state,g_tutuparam.shake_time,
            g_tututcp.is_connect(),g_tutuconfig.enable_status);   
        }     
#else 
        if(tutu_process_time_count % 10 == 0){
            TUTU_LOGI(TAG, "-----t=%ld--mode=%d--shake=%d--shaketime=%ld--connect=%d--ril=%d--gps=%d---",
            tutu_process_time_count,g_tutuconfig.mode,g_tutuparam.shake_state,g_tutuparam.shake_time,
            g_tututcp.is_connect(),5, 1);
            tutuapi_send_net_logger_debug("t=%ld,mode=%d,shake=%d,shaketime=%ld,connect=%d,status=%d",
            tutu_process_time_count,g_tutuconfig.mode,g_tutuparam.shake_state,g_tutuparam.shake_time,
            g_tututcp.is_connect(),g_tutuconfig.enable_status);   
        }
#endif
          
            
        if (tutu_process_time_count > 0xfffffff0) {
            tutu_process_time_count = 0;
        }

        //每隔10小时左右，网络校准时间
        if(tutu_process_time_count % 36001 == 36000 && g_tutuparam.server_connected == 1){
            tutuapi_send_synctime_msg();//请求服务器同步时间
        }       

        //低电告警检测
        tutucore_check_low_voltage();
        //如果系统持续运行超过3天，并且静止时间持续超过1小时，则重启系统,避免运行过久容易造成内存碎片
        if(tutu_process_time_count > 259200 && g_tutuparam.quiet_time > 3600){
            TUTU_LOGI(TAG, "RST %s:%d", __FUNCTION__, __LINE__);
            g_tutuos.restart();
        }
        // TUTU_LOGI(TAG, "m5");
    }
}

//用来监控main task是否被其他业务卡住
void tutucore_main_task_watch(void *params){
#if 1
    uint32_t loop_tick;
    uint32_t t = 0;
    int co = 0;

    while(1){
        g_tutuos.sleep(1);  // 使用 1s           
        loop_tick++; 

        //工厂模式
        if(tutu_factory_test_mode == 1){
            continue;
        }

        TUTU_LOGI(TAG, ">>>");

        if(tutu_factory_test_mode != 1 && tutu_process_time_count > 0){//如果不是工厂模式，则开始监控
            if(t != tutu_process_time_count){
                t = tutu_process_time_count;
                co = 0;
            }else{
                co ++;
            }
            
            if(co > 20){
                TUTU_LOGI(TAG, "-------!!!watch main task not responding!!!-----(%ld:%ld:%d)",t,tutu_process_time_count,co);
                TUTU_LOGI(TAG, "RST %s:%d", __FUNCTION__, __LINE__);                
                co = 0;
                //如果超过60s无变化，则认为已经main task 卡住
                g_tutuos.sleep2(300);
                g_tutuos.restart();
            }
        }      

        xlx_action_task_frame();

        //检测心跳时间
        if((tutu_process_time_count % g_tutuconfig.snd_heart_time) == 0){
            g_tutuparam.flag_enter_heart_code = 1;
        }        

        //检测是否有系统重启任务
        if(g_tutuparam.restart_cfg.enable == 1){
            g_tutuparam.restart_cfg.time--;
            
            if(g_tutuparam.restart_cfg.time <= 0){
                g_tutuparam.restart_cfg.time = 0;
                g_tutuparam.restart_cfg.enable = 0;
                g_tutuos.restart();
                TUTU_LOGI(TAG, "RST %s:%d", __FUNCTION__, __LINE__);
            }
        }

        //检测是否有网络重启任务
        if(g_tutuparam.network_restart_cfg.enable == 1){
            g_tutuparam.network_restart_cfg.time--;
            if(g_tutuparam.network_restart_cfg.time <= 0){
                g_tutuparam.network_restart_cfg.time = 0;
                g_tutuparam.network_restart_cfg.enable = 0;

                //重置状态
                g_tutuparam.flag_enter_heart_code = 1;
                g_tutuparam.is_login_server = 0;
                g_tutuparam.server_connected = 0;

                TUTU_LOGI(TAG, "!!-network restart-!!");
            }
        }

        tutucore_reset_factory_test_mode();
        // TUTU_LOGI(TAG, "Free memory size: %d", g_tutuos.get_memory_free_size());        
    }
#endif    
}

extern void tutu_tms_service_init(void);


char get_app_all_init_flag(void){

    return tutu_app_init_all_flag;
}


//逻辑入口
void tutucore_enter(void){
    xlx_tms_service_init();  // 延时启动
    TutuTcpSocket_Init(&TUTUG(tcp));

    //监控线程，用来监控maintask是否被卡死
    tutu_core_main_watch_thread = g_tututhread.new_thread(1024 * 2, "MainWatch", 8, tutucore_main_task_watch); 
    tutu_core_main_task_thread = g_tututhread.new_thread(1024 * 2, "TutuMain", 9, tutucore_main_task);
    TUTU_LOGI(TAG, "%s() line:%d",__FUNCTION__,__LINE__);
#if 0    
    TutuTel_Init(&TUTUG(tel));              // sos call 开启一个线程
    TUTU_LOGI(TAG, "%s() line:%d",__FUNCTION__,__LINE__);

    tutu_tms_service_init();
    TUTU_LOGI(TAG, "%s() line:%d",__FUNCTION__,__LINE__);

    tutu_app_init_all_flag = 1;
    TUTU_LOGI(TAG, "%s(All init end) line:%d",__FUNCTION__,__LINE__);
#endif    
}

